package com.ericsson.enap.modules.ebmLog.task;

import com.ericsson.common.util.LogFileName;
import com.ericsson.common.util.LoggerUtils;
import com.ericsson.enap.modules.ebmLog.entity.CcSccVO;
import com.ericsson.enap.modules.ebmLog.entity.EbmEventVO;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.IndexModel;
import org.slf4j.Logger;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * @description: 执行ccScc第一部统计多线程处理任务
 * @author: wangjingshi
 * @create: 2021-04-20 16:03
 */
public class EbmDoCcSccTask implements Runnable{

    private Logger log = LoggerUtils.Logger(LogFileName.EbmLogJob);

    private String netid;
    private String localPath;
    private String dateTime;
    private Map<String, EbmEventVO> eventMap;
    private CountDownLatch latch;
    private MongoTemplate mongoTemplate;

    public EbmDoCcSccTask(String netid, String localPath, String dateTime, Map<String, EbmEventVO> eventMap, CountDownLatch latch, MongoTemplate mongoTemplate) {
        this.netid = netid;
        this.localPath = localPath;
        this.dateTime = dateTime;
        this.eventMap = eventMap;
        this.latch = latch;
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public void run() {
        log.info("==== do cc and scc statistic start ===== "+netid);
        try {
            //1、统计所有文件的cc和scc的success、reject、abort、ignore
            Map<String, CcSccVO> totalMap = StatisticCCAndSCC();
            //2、按照事件分类，整理录库格式
            Map<String, List<CcSccVO>> resultMap = ClassifyByEvent(eventMap,totalMap);
            //3、将结果集合录入数据库
            InsertMongoDB(resultMap,eventMap);


        } catch (IOException e) {
            log.info(" ===== IOException EbmDoCcSccTask StatisticCCAndSCC "+e.getMessage());
            e.printStackTrace();
        } catch (SQLException e) {
            log.info(" ===== SQLException EbmDoCcSccTask ClassifyByEvent "+e.getMessage());
            e.printStackTrace();
        } finally {
            latch.countDown();
            log.info("==== do cc and scc statistic end ===== "+netid);
        }
    }

    private Map<String,CcSccVO> StatisticCCAndSCC() throws IOException {
        File file = new File(localPath);
        String[] dir = file.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if (name.endsWith("ccscc.csv")) {
                    return true;
                }
                return false;
            }
        });
        Map<String,CcSccVO> map;
        List<Map<String,CcSccVO>> list = new ArrayList<Map<String,CcSccVO>>();
        for(int i=0;i<dir.length;i++) {
            InputStreamReader read = new InputStreamReader(new FileInputStream(localPath + dir[i]));
            BufferedReader bufferedReader = new BufferedReader(read);
            String templine = "";
            int lineCount = 0;
            boolean isContinue = true;//是否跳过
            String[] lineStr;
            CcSccVO vo;
            map = new HashMap<>();
            while((templine = bufferedReader.readLine())!=null) {
                lineCount++;
                if(lineCount==2) {
                    isContinue = false;//不跳过
                }
                if(isContinue) {
                    continue;
                }
                vo = new CcSccVO();
                lineStr = templine.split(",");
                if(lineStr.length==9&&eventMap.containsKey(lineStr[3]+"-"+lineStr[4])) {
                    vo.setDateTime(dateTime);
                    vo.setNetid(netid);
                    vo.setCause_code(lineStr[0]);
                    vo.setSub_cause_code(lineStr[1]);
                    vo.setEvent_type(lineStr[3]);
                    vo.setSub_event_type(lineStr[4]);
                    if(Integer.parseInt(lineStr[5])!=0){
                        vo.setSuccess(Integer.parseInt(lineStr[5]));
                        vo.setResult_type("SUCCESS");
                    }
                    if(Integer.parseInt(lineStr[6])!=0){
                        vo.setReject(Integer.parseInt(lineStr[6]));
                        vo.setResult_type("REJECT");
                    }
                    if(Integer.parseInt(lineStr[7])!=0){
                        vo.setAbort(Integer.parseInt(lineStr[7]));
                        vo.setResult_type("ABORT");
                    }
                    if(Integer.parseInt(lineStr[8])!=0){
                        vo.setIgnore(Integer.parseInt(lineStr[8]));
                        vo.setResult_type("IGNORE");
                    }
                    vo.setValue(Integer.parseInt(lineStr[5])+Integer.parseInt(lineStr[6])+Integer.parseInt(lineStr[7])+Integer.parseInt(lineStr[8]));
                    map.put(lineStr[0]+"-"+lineStr[1]+"-"+lineStr[3]+"-"+lineStr[4], vo);
                }
            }
            list.add(map);
            bufferedReader.close();
            read.close();
        }
        Map<String,CcSccVO> totalMap = list.get(0);
        //将所有文件产生的map汇总
        for(int i=1;i<list.size();i++) {
            for (Map.Entry<String, CcSccVO> entry : list.get(i).entrySet()) {
                //如果totalMap中包含当前遍历的key值,则对结果进行汇总累加,若不包含,则将这组key-value加入汇总totalMap中
                if(totalMap.containsKey(entry.getKey())) {
                    totalMap.get(entry.getKey()).setSuccess(totalMap.get(entry.getKey()).getSuccess()+entry.getValue().getSuccess());
                    totalMap.get(entry.getKey()).setReject(totalMap.get(entry.getKey()).getReject()+entry.getValue().getReject());
                    totalMap.get(entry.getKey()).setAbort(totalMap.get(entry.getKey()).getAbort()+entry.getValue().getAbort());
                    totalMap.get(entry.getKey()).setIgnore(totalMap.get(entry.getKey()).getIgnore()+entry.getValue().getIgnore());
                    totalMap.get(entry.getKey()).setValue(totalMap.get(entry.getKey()).getValue()+entry.getValue().getValue());
                }else {
                    totalMap.put(entry.getKey(), entry.getValue());
                }
            }
        }
        return totalMap;
    }

    private Map<String,List<CcSccVO>> ClassifyByEvent(Map<String, EbmEventVO> eventMap, Map<String, CcSccVO> totalMap) {
        Map<String,List<CcSccVO>> resultMap = new HashMap<>();
        for(Map.Entry<String, EbmEventVO> entry : eventMap.entrySet()) {
            List<CcSccVO> list = new ArrayList<>();
            resultMap.put(entry.getKey(), list);
        }
        for(Map.Entry<String, CcSccVO> entry : totalMap.entrySet()) {
            CcSccVO vo = entry.getValue();
            resultMap.get(vo.getEvent_type()+"-"+vo.getSub_event_type()).add(vo);
        }
        return resultMap;
    }

    private void InsertMongoDB(Map<String, List<CcSccVO>> resultMap, Map<String, EbmEventVO> eventMap) throws SQLException{
        String tableDateTime = dateTime.substring(0, 10).replaceAll("-", "_");
        for(Map.Entry<String, List<CcSccVO>> entry:resultMap.entrySet()){
            String type = eventMap.get(entry.getKey()).getEventName();
            String collectionName = tableDateTime + "_"+type+"_query_statistics";
            if(!mongoTemplate.collectionExists(collectionName)){
                List<IndexModel> indexModelList = new ArrayList<>();
                BasicDBObject index = new BasicDBObject();
                index.put("netid",1);
                index.put("dateTime",1);
                index.put("cause_code",1);
                index.put("sub_cause_code",1);
                indexModelList.add(new IndexModel(index));
                mongoTemplate.createCollection(collectionName).createIndexes(indexModelList);
            }
            mongoTemplate.insert(entry.getValue(),collectionName);
        }
    }
}
